use wasm_bindgen::prelude::*;

#[wasm_bindgen]
#[derive(Debug, Clone)]
pub struct Transform {
    x: f32,
    y: f32,
    width: f32,
    height: f32,
}

#[wasm_bindgen]
impl Transform {
    #[wasm_bindgen(constructor)]
    pub fn new(x: f32, y: f32, width: f32, height: f32) -> Transform {
        Transform {
            x,
            y,
            width,
            height,
        }
    }

    #[wasm_bindgen(getter)]
    pub fn x(&self) -> f32 {
        self.x
    }

    #[wasm_bindgen(setter)]
    pub fn set_x(&mut self, value: f32) {
        self.x = value;
    }

    #[wasm_bindgen(getter)]
    pub fn y(&self) -> f32 {
        self.y
    }

    #[wasm_bindgen(setter)]
    pub fn set_y(&mut self, value: f32) {
        self.y = value;
    }

    #[wasm_bindgen(getter)]
    pub fn width(&self) -> f32 {
        self.width
    }

    #[wasm_bindgen(setter)]
    pub fn set_width(&mut self, value: f32) {
        self.width = value;
    }

    #[wasm_bindgen(getter)]
    pub fn height(&self) -> f32 {
        self.height
    }

    #[wasm_bindgen(setter)]
    pub fn set_height(&mut self, value: f32) {
        self.height = value;
    }
}

#[wasm_bindgen]
#[derive(Debug, Clone)]
pub struct FontStyle {
    color: String,
    size: u8,
}

#[wasm_bindgen]
impl FontStyle {
    #[wasm_bindgen(constructor)]
    pub fn new(color: String, size: u8) -> FontStyle {
        FontStyle { color, size }
    }

    pub fn default() -> FontStyle {
        FontStyle {
            color: String::from("#000"),
            size: 12,
        }
    }

    #[wasm_bindgen(getter)]
    pub fn color(&self) -> String {
        self.color.clone()
    }

    #[wasm_bindgen(setter)]
    pub fn set_color(&mut self, value: String) {
        self.color = value;
    }

    #[wasm_bindgen(getter)]
    pub fn size(&self) -> u8 {
        self.size
    }

    #[wasm_bindgen(setter)]
    pub fn set_size(&mut self, value: u8) {
        self.size = value;
    }
}

#[wasm_bindgen]
#[derive(Debug, Clone, Copy)]
pub enum BorderKind {
    None = "none",
    Dotted = "dotted",
    Solid = "solid",
    Dashed = "dashed",
}

#[wasm_bindgen]
#[derive(Debug, Clone)]
pub struct BorderStyle {
    color: String,
    width: u8,
    kind: BorderKind,
}

#[wasm_bindgen]
impl BorderStyle {
    #[wasm_bindgen(constructor)]
    pub fn new(color: String, width: u8, kind: BorderKind) -> BorderStyle {
        BorderStyle { color, width, kind }
    }

    pub fn default() -> BorderStyle {
        BorderStyle {
            color: "#000".into(),
            width: 1,
            kind: BorderKind::None,
        }
    }

    #[wasm_bindgen(getter)]
    pub fn color(&self) -> String {
        self.color.clone()
    }

    #[wasm_bindgen(setter)]
    pub fn set_color(&mut self, value: String) {
        self.color = value;
    }

    #[wasm_bindgen(getter)]
    pub fn width(&self) -> u8 {
        self.width
    }

    #[wasm_bindgen(setter)]
    pub fn set_width(&mut self, value: u8) {
        self.width = value;
    }

    #[wasm_bindgen(getter)]
    pub fn kind(&self) -> BorderKind {
        self.kind
    }

    #[wasm_bindgen(setter)]
    pub fn set_kind(&mut self, value: BorderKind) {
        self.kind = value;
    }
}

#[wasm_bindgen]
#[derive(Debug, Clone)]
pub struct Style {
    font: FontStyle,
    border: BorderStyle,
}

#[wasm_bindgen]
impl Style {
    #[wasm_bindgen(constructor)]
    pub fn new(font: FontStyle, border: BorderStyle) -> Style {
        Style { font, border }
    }

    pub fn default() -> Style {
        Style {
            font: FontStyle::default(),
            border: BorderStyle::default(),
        }
    }

    #[wasm_bindgen(getter)]
    pub fn font(&self) -> FontStyle {
        self.font.clone()
    }

    #[wasm_bindgen(setter)]
    pub fn set_font(&mut self, value: FontStyle) {
        self.font = value;
    }

    #[wasm_bindgen(getter, js_name = fontColor)]
    pub fn font_color(&self) -> String {
        self.font.color()
    }

    #[wasm_bindgen(setter, js_name = fontColor)]
    pub fn set_font_color(&mut self, value: String) {
        self.font.set_color(value);
    }

    #[wasm_bindgen(getter, js_name = fontSize)]
    pub fn font_szie(&self) -> u8 {
        self.font.size()
    }

    #[wasm_bindgen(setter, js_name = fontSize)]
    pub fn set_font_size(&mut self, value: u8) {
        self.font.set_size(value);
    }

    #[wasm_bindgen(getter)]
    pub fn border(&self) -> BorderStyle {
        self.border.clone()
    }

    #[wasm_bindgen(setter)]
    pub fn set_border(&mut self, value: BorderStyle) {
        self.border = value;
    }

    #[wasm_bindgen(getter, js_name = borderColor)]
    pub fn border_color(&self) -> String {
        self.border.color()
    }

    #[wasm_bindgen(setter, js_name = borderColor)]
    pub fn set_border_color(&mut self, value: String) {
        self.border.set_color(value);
    }

    #[wasm_bindgen(getter, js_name = borderWidth)]
    pub fn border_width(&self) -> u8 {
        self.border.width()
    }

    #[wasm_bindgen(setter, js_name = borderWidth)]
    pub fn set_border_width(&mut self, value: u8) {
        self.border.set_width(value);
    }

    #[wasm_bindgen(getter, js_name = borderKind)]
    pub fn border_kind(&self) -> BorderKind {
        self.border.kind()
    }

    #[wasm_bindgen(setter, js_name = borderKind)]
    pub fn set_border_kind(&mut self, value: BorderKind) {
        self.border.set_kind(value);
    }
}
